package demo;

import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.IOException;

import org.apache.lucene.analysis.cjk.CJKAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class Indexer {
	private IndexWriter writer=null;
	public static class TextFilesFilter implements FileFilter {
		public boolean accept(File path) {
			// 6) Index .txt only.
			return path.getName().toLowerCase().endsWith(".txt");
		}
	}

	public Indexer(String indexDir) throws IOException {
		Directory dir = FSDirectory.open(new File(indexDir));
		// 3) Create Lucene IndexWriter.
		// http://www.cnblogs.com/lvpei/articles/1731813.html
		IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_36, 
				                                         new CJKAnalyzer(Version.LUCENE_36));
		writer = new IndexWriter(dir, config);
	}
	
	public void close() throws IOException {
		// 4) Close IndexWriter
		writer.close();
	}
	
	/**
	 * BD: Index all files in given directory. (Not recursively)
	 * @param dataDir: Directory to do indexing
	 * @param filter: File filter to skip unwanted file type.
	 * @return Number of indexed file.
	 * @throws Exception
	 */
	public int index(String dataDir, FileFilter filter) throws Exception {
		File[] files = new File(dataDir).listFiles();
		for (File f : files) {
			if (!f.isDirectory() && !f.isHidden() && f.exists() && f.canRead()
					&& (filter == null || filter.accept(f))) {
				indexFile(f);
			}
		}
		return writer.numDocs(); // 5) Return the number of indexed docs.
	}
	
	/**
	 * BD: Translated into indexed file into Document.
	 * @param f: Index file
	 * @return Document object
	 * @throws Exception
	 */
	protected Document getDocument(File f) throws Exception {
		Document doc = new Document();
		doc.add(new Field("contents", new FileReader(f))); // 7) Index file content.
		doc.add(new Field("filename", f.getName(), Field.Store.YES, Field.Index.NOT_ANALYZED)); // 8) Index filename
		doc.add(new Field("fullpath", f.getCanonicalPath(), Field.Store.YES, Field.Index.NOT_ANALYZED)); // 9) Index full path
		return doc;
	}
	
	/**
	 * BD: Index given file
	 * @param f: File to be indexed.
	 * @throws Exception
	 */
	private void indexFile(File f) throws Exception {
		System.out.println("Indexing " + f.getCanonicalPath());
		Document doc = getDocument(f);
		writer.addDocument(doc); // 10) Add doc to Lucene index
	}
	
	public static void main(String[] args) throws Exception {
		if (args.length != 2) {
			throw new IllegalArgumentException("Usage: java "
					+ Indexer.class.getName() + " <index dir> <data dir>");
		}
		String indexDir = args[0];  // 1) Create index in this directory
		String dataDir = args[1];	// 2) Index *.txt from this directory
		long start = System.currentTimeMillis();
		Indexer indexer = new Indexer(indexDir);
		int numIndexed;
		try {
			numIndexed = indexer.index(dataDir, new TextFilesFilter());
		} finally {
			indexer.close();
		}
		long end = System.currentTimeMillis();
		System.out.println("Indexing " + numIndexed + " files took "
				+ (end - start) + " milliseconds");
	}
}
